#include <xstring>
#include "ATKConnectorDll.h"
#include "mex.h"

static int mexATKConnect(char* strOperate)
{
	int nConID = 0;
	if (strcmp("atkOpen", strOperate) == 0)
	{
		nConID = atkOpen();
	}
	return nConID;
}

static int mexATKConnect(char* strOperate, char* strIP, int nPORT)
{
	int nConID = 0;
	unsigned short unPort = 0;
	if (strcmp("atkOpen", strOperate) == 0)
	{
		unPort = (unsigned short)nPORT;
		nConID = atkOpen(strIP, unPort);
	}
	return nConID;
}

static char* mexATKConnect(char* strOperate, int nConID, char* strRHS0, char* strRHS1)
{
	char* scReturn;
	std::string strRetutn = "";
	if (strcmp("atkConnect", strOperate) == 0)
	{
		strRetutn = atkConnectEx(nConID, strRHS0, strRHS1);
		scReturn = (char*)mxMalloc(strRetutn.length()+1);
		strcpy(scReturn, strRetutn.c_str());
	}
	return scReturn;
}

static void mexATKConnect(char* strOperate, int nConID)
{
	if (strcmp("atkClose", strOperate) == 0)
	{
		atkClose(nConID);
	}
}

static CmdResult mexATKConnect(char* strOperate, int nConID, char* strRHS0, char* strRHS1, char* strRHS2)
{
	if (strcmp("atkExecuteCommand", strOperate) == 0)
	{
		return atkExecuteCommand(nConID, strRHS1, strRHS2);
	}
}

void mexFunction(int nlhs, mxArray *plhs[],
	int nrhs, const mxArray*prhs[])
{
	double *dPORT;
	double *dConID;
	char* strReturn;
	CmdResult cCmdResult;
	char* strstrOperate;
	char* strIP;
	char* strRHS0;
	char* strRHS1;
	char* strRHS2;
	//const char* strfieldnames[1];
	//int dim[2] = {10, 255};
	if (1 == nrhs)
	{
		plhs[0] = mxCreateDoubleMatrix(1,1, mxREAL);
		strstrOperate = mxArrayToString(prhs[0]);
		dConID = mxGetPr(plhs[0]);
		*dConID = (double)mexATKConnect(strstrOperate);
	}
	else if (2 == nrhs)
	{
		strstrOperate = mxArrayToString(prhs[0]);
		dConID = mxGetPr(prhs[1]);
		mexATKConnect(strstrOperate, (int)*dConID);
	}
	else if (3 == nrhs)
	{
		plhs[0] = mxCreateDoubleMatrix(1,1, mxREAL);
		strstrOperate = mxArrayToString(prhs[0]);
		strIP = mxArrayToString(prhs[1]);
		dPORT = mxGetPr(prhs[2]);
		dConID = mxGetPr(plhs[0]);
		*dConID = (double)mexATKConnect(strstrOperate, strIP, (int)*dPORT);
	}
	else if (4 == nrhs)
	{
		strstrOperate = mxArrayToString(prhs[0]);
		dConID = mxGetPr(prhs[1]);
		strRHS0 = mxArrayToString(prhs[2]);
		strRHS1 = mxArrayToString(prhs[3]);
		//strfieldnames[0] = mxArrayToString(prhs[0]);
		strReturn = mexATKConnect(strstrOperate, (int)*dConID, strRHS0, strRHS1);
		if (strlen(strReturn) > 0)
        {
            if (strcmp("NACK", strReturn) == 0)
            {
                //mexATKConnect("atkClose", (int)*dConID);
                mexErrMsgIdAndTxt("MATLAB:mexATKConnect:atkConnect", "atkConnect:  error during processing of Connect command, check command for valid syntax.");
            }
            else 
            {
                plhs[0] = mxCreateStringFromNChars_730(strReturn, strlen(strReturn)-1);
				//plhs[0] = mxCreateStructMatrix(1, 2, 1, strfieldnames);
				//plhs[0] = mxCreateNumericArray(2, dim);
            }
        }
        else
        {
            plhs[0] = mxCreateDoubleMatrix(0,0, mxREAL);
        }
        mxFree(strReturn);
	}
	else if (5 == nrhs)
	{
		strstrOperate = mxArrayToString(prhs[0]);
		dConID = mxGetPr(prhs[1]);
		strRHS0 = mxArrayToString(prhs[2]);
		strRHS1 = mxArrayToString(prhs[3]);
		strRHS2 = mxArrayToString(prhs[4]);
		cCmdResult = mexATKConnect(strstrOperate, (int)*dConID, strRHS0, strRHS1, strRHS2);
		if (cCmdResult.m_vectData.size() > 0)
		{
			plhs[0] = mxCreateCellMatrix(1, cCmdResult.m_vectData.size());
			for (int nIndex = 0; nIndex < cCmdResult.m_vectData.size(); nIndex++)
			{
				mxSetCell(plhs[0], nIndex, mxCreateString(cCmdResult.m_vectData[nIndex].c_str()));
			}
		}
		else
		{
			plhs[0] = mxCreateDoubleMatrix(0,0, mxREAL);
		}
	}
	else
	{
        //mexATKConnect("atkClose", (int)*dConID);
		mexErrMsgIdAndTxt("MATLAB:mexATKConnect:invalidNumInputs", "One input arguments required.");
	}
}